﻿using System;
using System.Collections.Generic;

namespace ArtemisExtensions
{
    /// <summary>
    /// Manages the components in the universe
    /// </summary>
    public sealed class ComponentManager : ArtemisExtensions.IComponentManager
    {
        public ComponentManager()
        {
            MasterList = new Dictionary<Type, List<IComponent>>();
        }

        /// <summary>
        /// The master list of all components in this Universe
        /// </summary>
        /// <remarks>
        /// Type - Stores the "marker" for this set of components, for easy identification
        /// (nixed) Long - Stores the ID for the t that keeps this component
        /// C_Component - Reference to the actual component being stored
        /// </remarks>
        private System.Collections.Generic.Dictionary<System.Type, System.Collections.Generic.List<ArtemisExtensions.IComponent>> MasterList
        {
            get;
            set;
        }

        public void AddNewComponent(C_Component c)
        {
            List<IComponent> l;

            //does this component type already exist in the list?
            if (MasterList.TryGetValue(c.GetType(), out l))
            {
                //if so, then put the component in with that type
                l.Add(c);
            }
            else
            {
                //if not, then create the component type along with a new list in the MasterList
                l = new List<IComponent>();
                l.Add(c);
                MasterList.Add(c.GetType(), l);
            }
        }

        /// <summary>
        /// RemoveCombatant component c from entity compare.
        /// </summary>
        /// <remarks>Find the type from c, so we can narrow down of the first list. Then use compare to narrow down next list</remarks>
        public void RemoveComponent(IComponent c)
        {
            //find the component type in Master
            List<IComponent> cl;
            if (!MasterList.TryGetValue(c.GetType(), out cl))
            {
                //nothing here
                return;
            }

            //find the component in the list of that type
            cl.Remove(c);

            //is the list now empty? if so, remove the entry in Master
            if (cl.Count <= 0)
            {
                MasterList.Remove(cl.GetType());
            }
        }

        public List<IComponent> GetAllComponents()
        {
            List<IComponent> retval = new List<IComponent>();

            foreach (List<IComponent> cl in MasterList.Values)
            {
                retval.AddRange(cl);
            }
            return retval;
        }

        public List<IComponent> GetAllComponents(Type t)
        {
            List<IComponent> l;
            if (MasterList.TryGetValue(t, out l))
            {
                return l;
            }
            else
            {
                return null;
            }
        }
    }
}